package com.aliyun.messagemgt.service;

import com.alibaba.fastjson.JSONObject;
import com.aliyun.messagemgt.common.dto.send.*;
import com.aliyun.messagemgt.common.enums.ChannelTypeEnum;
import com.aliyun.messagemgt.common.enums.PushResultEnum;
import com.aliyun.messagemgt.sendplugin.SendStrategy;
import com.aliyun.messagemgt.sendplugin.SendStrategyFactory;
import com.aliyun.messagemgt.util.AlibabaHttpUtil;
import com.aliyun.messagemgt.util.redis.Redis;
import com.google.common.base.CaseFormat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class LanXinPlusSendStrategy implements SendStrategy, InitializingBean {

    private static final Logger logger = LoggerFactory.getLogger(LanXinPlusSendStrategy.class);

    @Override
    public void afterPropertiesSet() {
        SendStrategyFactory.register(ChannelTypeEnum.LANXIN_PLUS.getType(), this);
    }

    @Override
    public void sendMessage(PushChannelInfo pushChannelInfo, MsgRecordVO msgRecordVO) {
        //1、检查参数合法性
        if (null == pushChannelInfo || null == msgRecordVO) {
            logger.error("lan-xin-plus -> sendMessage pushChannelInfo or msgRecordVO is null");
            return;
        }
        if (org.apache.commons.lang3.StringUtils.isEmpty(pushChannelInfo.getApiUrl()) ||
                org.apache.commons.lang3.StringUtils.isEmpty(pushChannelInfo.getApiAppKey()) ||
                org.apache.commons.lang3.StringUtils.isEmpty(pushChannelInfo.getApiAppSecret()) ||
                org.apache.commons.lang3.StringUtils.isEmpty(pushChannelInfo.getGrandType())) {
            logger.error("lan-xin-plus -> sendMessage apiUrl、appId、secret、grandType is null");
            return;
        }
        if (CollectionUtils.isEmpty(msgRecordVO.getReceivers())) {
            logger.error("lan-xin-plus -> sendMessage msgRecordVO.getReceivers() is empty");
            return;
        }
        if (CollectionUtils.isEmpty(msgRecordVO.getContents()) ||
                null == msgRecordVO.getContents().get(0) ||
                org.apache.commons.lang3.StringUtils.isEmpty(msgRecordVO.getContents().get(0).getContent())) {
            logger.error("lan-xin-plus -> sendMessage msgRecordVO.getContents() is empty");
            return;
        }

        //消息推送人工号
        List<String> employeeCodes = msgRecordVO.getReceivers().stream().map(Receiver::getEmployeeCode).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(employeeCodes)) {
            return;
        }
        //3、准备变量
        logger.info("lan-xin-plus push api:{}", pushChannelInfo.getApiUrl());
        List<MsgMiddleResult> results = msgRecordVO.getResults();
        String apiUrl = pushChannelInfo.getApiUrl();
        String grandType = pushChannelInfo.getGrandType();
        String appId = pushChannelInfo.getApiAppKey();
        String secret = pushChannelInfo.getApiAppSecret();

        List<String> stuffIds = getStuffId(employeeCodes, apiUrl, appId, secret, grandType);

        String appToken = getAppToken(apiUrl, appId, secret, grandType);

        String url = String.format("%s%s?app_token=%s", apiUrl, LanXinPlusConstant.SEND_MSG_API, appToken);

        JSONObject msgJson = new JSONObject();
        msgJson.put("userIdList", stuffIds);
        JSONObject contentJson = new JSONObject();
        MsgBody msgBody = msgRecordVO.getContents().get(0);
        JSONObject textJson = new JSONObject();
        if (LanXinPlusConstant.MSG_TYPE_LINK_CARD.equals(msgBody.getType())) {
            String msgType = CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, msgBody.getType());
            msgJson.put("msgType", msgType);
            contentJson.put("linkCard", JSONObject.parseObject(msgBody.getContent()));
        } else {
            msgJson.put("msgType", LanXinPlusConstant.MSG_TYPE_TEXT);
            contentJson.put("text", textJson);
            textJson.put("content", msgBody.getContent());
        }
        msgJson.put("msgData", contentJson);
        String request = AlibabaHttpUtil.httpRequest(url, HttpMethod.POST.name(), msgJson.toJSONString());
        String content = null;
        Integer pushResultCode = PushResultEnum.PUSH_SUCCESS.getErrorCode();
        if (StringUtils.isEmpty(request)) {
            content = "lan-xin-plus return msg is null";
            pushResultCode = PushResultEnum.LAN_XIN_PLUS_PUSH_ERROR.getErrorCode();
        } else {
            LanXinPlusBaseInfo lanXinPlusBaseInfo = JSONObject.parseObject(request, LanXinPlusBaseInfo.class);
            if (!lanXinPlusBaseInfo.getErrCode().equals(0)) {
                content = lanXinPlusBaseInfo.getErrMsg();
                pushResultCode = PushResultEnum.LAN_XIN_PLUS_PUSH_ERROR.getErrorCode();
            }
        }
        MsgMiddleResult msgMiddleResult = new MsgMiddleResult().setPushResultCode(pushResultCode)
                .setPushResultDescription(content).setReceivers(msgRecordVO.getReceivers());
        results.add(msgMiddleResult);
    }


    private String getAppToken(String address, String appId, String secret, String grandType) {
        logger.info("lan—xin-plus getAppToken");
        String redisKey = String.format("APP_TOKEN_%s", appId);
        String appToken = Redis.getValue(redisKey);
        if (StringUtils.isEmpty(appToken)) {
            String url = String.format("%s%s?appid=%s&secret=%s&grant_type=%s", address, LanXinPlusConstant.APP_TOKEN_API, appId, secret, grandType);
            String returnMsg = AlibabaHttpUtil.httpRequest(url, HttpMethod.GET.name(), null);
            if (StringUtils.isEmpty(returnMsg)) {
                throw new RuntimeException("lan-xin-plus app_token is null");
            }
            LanXinPlusQryAppTokenResult lanXinPlusQryAppTokenResult = JSONObject.parseObject(returnMsg, LanXinPlusQryAppTokenResult.class);
            if (lanXinPlusQryAppTokenResult.getErrCode().equals(0)) {
                LanXinPlusQryAppTokenResult.Result result = lanXinPlusQryAppTokenResult.getData();
                Redis.setXX(redisKey, result.getAppToken(), 6);
                return result.getAppToken();
            } else {
                throw new RuntimeException(lanXinPlusQryAppTokenResult.getErrMsg());
            }
        }
        return appToken;
    }


    private List<String> getStuffId(List<String> employeeCodes, String address, String appId, String secret, String grandType) {
        List<String> stuffIdList = new ArrayList<>();
        //蓝信约定orgId取appId的前半部分
        String orgId = appId.split("-")[0];
        employeeCodes.stream().distinct().collect(Collectors.toList()).forEach(employeeCode -> {
            String appToken = getAppToken(address, appId, secret, grandType);
            String url = String.format("%s%s?app_token=%s&org_id=%s&id_type=%s&id_value=%s", address, LanXinPlusConstant.QUERY_STUFF_ID_API, appToken, orgId, "employ_id", employeeCode);
            String request = AlibabaHttpUtil.httpRequest(url, HttpMethod.GET.name(), null);
            if (!StringUtils.isEmpty(request)) {
                LanXinPlusQryStuffIdResult lanXinPlusQryStuffIdResult = JSONObject.parseObject(request, LanXinPlusQryStuffIdResult.class);
                if (lanXinPlusQryStuffIdResult.getErrCode().equals(0)) {
                    LanXinPlusQryStuffIdResult.Result result = lanXinPlusQryStuffIdResult.getData();
                    stuffIdList.add(result.getStaffId());
                }
            }
        });
        return stuffIdList;
    }
}
